package cn.edu.pku.ss.lbs.service;

import cn.edu.pku.ss.lbs.blip.BlipUtility;
import cn.edu.pku.ss.lbs.content.Zone;
import cn.edu.pku.ss.lbs.content.ZoneDatabase;
import cn.edu.pku.ss.lbs.location.Target;
import cn.edu.pku.ss.lbs.location.TargetDatabase;
import cn.edu.pku.ss.lbs.position.ProximitySignalProcessor;
import cn.edu.pku.ss.lbs.position.SignalSource;

import java.util.*;

public class LBSService { // todo : �淶�ӿں����
    private static LBSService ourInstance;

    public static LBSService getInstance() {
        if (ourInstance == null) ourInstance = new LBSService();
        return ourInstance;
    }

    private TargetDatabase targetDatabase = new TargetDatabase();
    private ZoneDatabase zoneDatabase = new ZoneDatabase();
    private ProximitySignalProcessor proximity = new ProximitySignalProcessor();

    private LBSService() {
        SignalSource source = BlipUtility.getInstance().getSignalSource();
        source.addSignalProcessor(proximity);
    }

    public String getZone(int x, int y) {
        Zone zone = zoneDatabase.getZone(x, y);
        if (zone == null) return null;
        return zone.getId();
    }

    public List<String> getZoneList() {
        List<Zone> zoneList = zoneDatabase.getAllZones();
        List<String> result = new ArrayList<String>();
        for (Zone zone : zoneList) {
            result.add(zone.getId());
        }
        return result;
    }

    public Map<String, String> getUsers(String zone) {
        Set<String> terminals = proximity.getTerminals(zone, System.currentTimeMillis());
        Map<String, String> result = new HashMap<String, String>();
        for (String terminal : terminals) {
            Target target = targetDatabase.getTargetByTerminal(terminal);
            if (target == null) result.put("Unknown User", terminal);
            else result.put(target.getId(), terminal);
        }
        return result;
    }

    public void sendMessage(String zone, String terminal, String message) {
        BlipUtility.getInstance().sendMessage(zone, terminal, message);
    }

    public void sendFile(String zone, String terminal, String path) {
        BlipUtility.getInstance().sendFile(zone, terminal, path);
    }

    public String getZoneByUserName(String user) {
        String terminal = targetDatabase.getTargetById(user).getTerminalId();
        return proximity.getStation(terminal, System.currentTimeMillis());
    }

    public String getZoneByTerminal(String btAddr) {
        return proximity.getStation(btAddr, System.currentTimeMillis());
    }

    public void sendMessage(String zone, String message) {
        Map<String, String> users = getUsers(zone);
        System.out.println("users.size(): " + users.size());
        for (String terminal : users.values()) {
            sendMessage(zone, terminal, message);
        }
    }

    public void sendFile(String zone, String path) {
        Map<String, String> users = getUsers(zone);
        for (String terminal : users.values()) {
            sendFile(zone, terminal, path);
        }
    }

    public Map<String, Map<String, Zone>> getUsers() {
        Map<String, Map<String, Zone>> allUsers = new HashMap<String, Map<String, Zone>>();
        List<Zone> zoneList = zoneDatabase.getAllZones();
        for (Zone zone : zoneList) {
            Map<String, String> usersInZone = getUsers(zone.getId());
            Map<String, Zone> users = new HashMap<String, Zone>();
            for (String btAddr : usersInZone.values()) {
                users.put(btAddr, zone);
            }
            allUsers.put(zone.getId(), users);
        }
        return allUsers;
    }
}